use std::{
    env,
    sync::{mpsc, Arc, Mutex},
    thread,
    net::TcpStream,
    io::{prelude::*, BufReader},
};

// 1.定义ThreadPool结构体创建线程池
pub struct ThreadPool {
    workers: Vec<Worker>,
    sender: Option<mpsc::Sender<Job>>,
}
// 1.1实现ThreadPool线程池的new、execute方法
impl ThreadPool {
    pub fn new(size: usize) -> ThreadPool {
        // 创建线程数
        assert!(size > 0);
        let cpu_core_num = thread::available_parallelism().unwrap().get();
        let thread_num = |s:usize| if s >= cpu_core_num { cpu_core_num } else { s };
        // 创建workers容量
        let mut workers = Vec::with_capacity(thread_num(size));
        // 创建生产消费
        let (sender, receiver) = mpsc::channel();
        let receiver = Arc::new(Mutex::new(receiver));
        for id in 0..thread_num(size) {
            workers.push(Worker::new(id, Arc::clone(&receiver)));
        }
        Self {
            workers,
            sender: Some(sender),
        }
    }
    pub fn execute<F>(&self, f: F)
    where
        F: FnOnce() + Send + 'static,
    {
        let job = Box::new(f);
        self.sender.as_ref().unwrap().send(job).unwrap();
    }
}
// 1.2为ThreadPool实现Drop的trait特性达到自动清理线程
impl Drop for ThreadPool {
    fn drop(&mut self) {
        drop(self.sender.take().unwrap());
        for worker in &mut self.workers {
            println!("Shutting down worker {}", worker.id);
            if let Some(thread) = worker.thread.take() {
                thread.join().unwrap();
            }
        }
    }
}
// 2.定义Worker结构体创建线程
struct Worker {
    id: usize,
    thread: Option<thread::JoinHandle<()>>,
}
// 2.1实现Worker的new方法创建线程
impl Worker {
    fn new(id:usize, receiver:Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker {
        let thread = thread::spawn(move || loop {
           let message = receiver.lock().unwrap().recv();
            match message {
                Ok(job) => {
                    println!("Worker {id} got a job; executing...");
                    job();
                }
                Err(_) => {
                    println!("Worker {} disconnected; shutting down!", id);
                    break;
                }
            }
        });
        Self {
            id,
            thread: Some(thread),
        }
    }
}
// 3.定义任务Job类型,Job为trait对象的类型别名
type Job = Box<dyn FnOnce() + Send + 'static>;

// 4.根据输入参数自定义TCP协议端口函数
fn get_port() -> u16 {
    let args:Vec<String> = env::args().collect();
    if args.len() <= 1 {
        7878
    } else {
        args[1].parse().expect("Amount of arguments is invalid")
    }
}
pub const PORT: fn() -> u16 = get_port;
// 5.定义handle_connection函数处理TCP流数据
pub fn handle_connection(mut stream: TcpStream) {
    let port = PORT();
    let buf_reader = BufReader::new(&mut stream);
    let request_line = buf_reader.lines().next().expect("Ipv6 Address already is Error,Please change.").unwrap();
    let (status_line, contents) = match request_line.split_whitespace().next().unwrap() {
        "GET"|"POST"|"DEL"|"PUT" => ("HTTP/1.1 200 OK\r\n\r\n", format!("Http request method are {}, Accessible port: {}", request_line, port)),
        _ => ("HTTP/1.1 404 NOT FOUND\r\n\r\n", format!("Not found: {}", request_line)),
    };
    let length = contents.len();
    let res=format!("{status_line}\r\nContent-Lenght:{length}\r\n{contents}");
    stream.write_all(res.as_bytes()).unwrap();
    stream.flush().unwrap();
}